package y.q.h.service.impl;





import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import y.q.h.entity.TAdmin;
import y.q.h.mapper.EntityDao;
import y.q.h.mapper.SuperbDao;
import y.q.h.service.SuperService;
import y.q.h.util.apicontroller.R;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static y.q.h.util.apicontroller.R.failed;
import static y.q.h.util.apicontroller.R.success;


/**
 * (User05)表服务实现类
 *
 * @author SongRenShuo
 * @since 2023-08-18 01:22:22
 */
@Service
public class SuperServiceImpl<T, ID extends Serializable> implements SuperService<T, ID> {
    @Autowired
    private SuperbDao<T, ID> superbDao;
    @Autowired
    private EntityDao<T, ID> entityDao;

    /**
     * 新增数据
     *
     * @param entity 实体对象
     * @return 影响行数
     */
    @Override
    public boolean insert(T entity) {
        if (!(entity instanceof Map)) {
            return entityDao.insert(entity) > 0;
        }
        return superbDao.insert(isPrimaryKey(entity)) > 0;
    }

    /**
     * 根据ID查询
     *
     * @param id 主键
     * @return 实体对象
     */
    @Override
    public T getById(ID id) {
        return entityDao.getById(id);
    }

    /**
     * 根据ID查询 - Map专用
     *
     * @param id id
     * @return {@link T}
     */
    @Override
    public T getById(T id) {
        return superbDao.getById(isPrimaryKey(id));
    }

    /**
     * 单查 - 根据账户密码
     *
     * @param entity 实体对象
     * @return 实体对象
     */
    @Override
    public T queryEntity(T entity) {
        T queryEntity;
        if (!(entity instanceof Map)) {
            try {
                //强转为实体类 - 准备二次判断密码是否正确
//                queryEntity =  isPassword(entity,entityDao.queryEntity(entity));
                queryEntity = entityDao.queryEntity(entity);
            } catch (Exception e) {
                queryEntity = null;
            }
        } else {
            try {
                queryEntity = superbDao.queryEntity(isPrimaryKey(entity));
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return queryEntity;
    }

    /**
     * 登录 - 五表联查
     *
     * @param entity 实体对象
     * @return {@link List}<{@link Map}>
     */
    @Override
    public List<Map> getRbac(T entity) {

        return entityDao.getRbac(entity);
    }

    /**
     * 修改数据
     *
     * @param entity 实体对象
     * @return 影响行数
     */
    @Override
    public boolean update(T entity) {
        if (!(entity instanceof Map)) {
            return entityDao.update(entity) > 0;
        }
        return superbDao.update(isPrimaryKey(entity)) > 0;
    }

    /**
     * 删除数据 - 通过ID
     *
     * @param id 主键
     * @return 影响行数
     */
    @Override
    public boolean deleteById(ID id) {
        return entityDao.deleteById(id) > 0;
    }

    /**
     * 删除数据 - 通过ID - Map专用
     *
     * @param id id
     * @return boolean
     */
    @Override
    public boolean deleteById(T id) {
        return superbDao.deleteById(isPrimaryKey(id)) > 0;
    }

    /**
     * 模糊查询 - 根据条件
     *
     * @param entity 实体对象
     * @return 实体对象列表
     */
    @Override
    public List queryLike(T entity) {
        if (!(entity instanceof Map)) {
            return entityDao.queryLike(entity);
        }
        return superbDao.queryLike(isPrimaryKey(entity));
    }

    /**
     * 分页查询 - 支持模糊查询
     *
     * @param page   当前页
     * @param limit  限制条数
     * @param entity 条件
     * @return {@link List}<{@link T}>
     */
    @Override
    public List getByRowBoundsLike(Integer page, Integer limit, T entity) {
        RowBounds rowBounds = new RowBounds((page - 1) * 10, limit);
        if (!(entity instanceof Map)) {
            return entityDao.getByRowBoundsLike(rowBounds, entity);
        }
        return superbDao.getByRowBoundsLike(rowBounds, isPrimaryKey(entity));
    }


    /**
     * 精确查询 - 根据条件
     *
     * @param entity 实体对象
     * @return 实体对象列表
     */
    @Override
    public List query(T entity) {
        if (!(entity instanceof Map)) {
            return entityDao.query(entity);
        }
        return superbDao.query(isPrimaryKey(entity));
    }

    /**
     * 分页查询 - 精确查询
     *
     * @param page   当前页
     * @param limit  限制条数
     * @param entity 条件
     * @return {@link List}<{@link T}>
     */
    @Override
    public List getByRowBounds(Integer page, Integer limit, T entity) {
        RowBounds rowBounds = new RowBounds((page - 1) * 10, limit);
        if (!(entity instanceof Map)) {
            return entityDao.getByRowBounds(rowBounds, entity);
        }
        return superbDao.getByRowBounds(rowBounds, isPrimaryKey(entity));
    }

    /**
     * 查询表中数据条数
     *
     * @param entity 实体
     * @return Integer
     */
    @Override
    public Integer count(T entity) {
        if (!(entity instanceof Map)) {
            return entityDao.count(entity);
        }
        return superbDao.count(isPrimaryKey(entity));
    }

    /**
     * 判定参数类型
     *
     * @param entity 实体
     */
    public T isPrimaryKey(T entity) {
        if (!(entity instanceof Map)) {
            System.out.println("实体类为：" + entity);
            return entity;
        }
        //当前map
        Map<String, Object> entityMap = (Map) entity;
        //总map - 实体map
        Map<String, Object> entitySuperb = new LinkedHashMap<>();
        //字段map
        Map<String, Object> columns = new LinkedHashMap<>();
        //主键map
        Map<String, Object> primaryKey = new LinkedHashMap<>();
        // 循环遍历entity的键值对
        for (Map.Entry<String, Object> entrySet : entityMap.entrySet()) {

            String key = entrySet.getKey();
            Object value = entrySet.getValue();

            // 判断key中是否包含"tableName"
            if (key.contains("tableName")) {
                entitySuperb.put("tableName", value);
                // 判断key中是否包含"id"
//            } else if (key.contains("id")) {
            } else if ("id".equals(key)) {
                // 将当前键值对存入entity的primaryKey中
                primaryKey.put(key, value);
                System.out.println("当前主键为：" + primaryKey);
            } else {
                columns.put(key, value);
            }
        }
        entitySuperb.put("primaryKey", primaryKey);
        entitySuperb.put("columns", columns);
        System.out.println("实体Map为：" + entitySuperb);
        return (T) entitySuperb;
    }

    /**
     * 验证密码方法
     *
     * @param entity       当前实体
     * @param returnEntity 查询结果实体
     * @return {@link T}
     */
    public T isPassword(T entity, T returnEntity) {
        // 判断参数类型
        if (entity instanceof TAdmin) {
            // 强转为User类型
            TAdmin user = (TAdmin) entity;
            // 强转为User类型
            TAdmin password = (TAdmin) returnEntity;
            // 计算用户的密码哈希值
            int hashedUser = user.getPassword() != null ? user.getPassword().hashCode() : 0;
            // 计算查询结果的密码哈希值
            int hashedPassword = password.getPassword() != null ? password.getPassword().hashCode() : 1;
            // 如果密码哈希值相等，则返回entity
            if (hashedUser == hashedPassword) {
                return entity;
            }
        }
        // 如果参数类型不是User，则返回null
        return null;
    }

    /**
     * 登录二次验证
     *
     * @param entity 实体
     * @return {@link Map}<{@link String}, {@link Object}>
     */
    @Override
    public R isAccount(T entity) {
        System.out.println("isAccount_entity" + entity);

        // 判断用户是否存在
        Integer count = count(entity);

        // 如果用户不存在，则返回错误信息
        if (count == 0) {
            return failed("用户不存在", entity);
        }

        // 查询用户
        List<Map> listMap = getRbac(entity);

        // 如果查询结果为空，则返回错误信息
        if (listMap.isEmpty()) {
            return failed("密码错误", entity);
        }

        // 标记密码是否匹配成功的变量
        boolean isPasswordMatch = false;

        // 遍历查询到的用户列表
        for (Map userMap : listMap) {
            String passwordFromDb = (String) userMap.get("password");

            // 检查密码是否匹配
            if (passwordFromDb.equals(((TAdmin) entity).getPassword())) {
                isPasswordMatch = true;
                break;
            }
        }

        // 如果密码匹配，则返回登录成功信息，否则返回密码错误信息
        if (!isPasswordMatch) {
            return failed("密码错误", entity);
        }
        return success(entity);

    }


}
